package com.ricchieri.model;

import java.sql.Date;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@Table(name="user")
public class User extends BaseEntity implements UserDetails {

	private static final long serialVersionUID = 6220080725771220681L;

	@Column(name="firstName", nullable=false, length=100)	
	private String firstName;
	
	@Column(name="lastName", nullable=false, length=100)
	private String lastName;
	
	@Column(name="password", nullable=false, length=256)
	private String password;
	
	@Column(name="lastLogin", nullable=true)
	private Date lastLogin;
	
	@Column(name="dni", nullable=false, length=9)
	private String dni;
	
	@Column(name="username", nullable=false, length=11)
	private String username;
	
	@Column(name="theme", nullable=false, length=25)
	private String theme;
	
	@Column(name="autorized", nullable=false)
	private Boolean autorized;
	
	@OneToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "documentType", nullable = false)
	private DocumentType documentType;
	
	@OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade=CascadeType.ALL)
	private List<UserRole> roles;
	
	@OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade=CascadeType.ALL)
	private List<UserPhone> userPhone;
	
	@OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade=CascadeType.ALL)
	private List<UserEmail> userEmail;
	
	@OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade=CascadeType.ALL)
	private List<Operation> operation;
	
	@Column(name="cuil", nullable=true, length=15)
	private String cuil;
	
	@Column(name="loginAttemp", nullable=false)
	private int loginAttemp = 0;

	@Column(name="block", nullable=false)
	private Boolean block = Boolean.FALSE;
	
	@Column(name="blockMotive", nullable=true, columnDefinition="TEXT")
	private String blockMotive;
	
	@Transient
	private String confirmPassword;
	
	public List <Role> getActiveRoles(){
		List <Role> activeRoles = new ArrayList<Role>();
		for (UserRole userRole : getRoles()) {
			if(userRole.isActive()) {
				activeRoles.add(userRole.getRole());
			}
		}
		return activeRoles;
	}


	public String getFullName(){
		return getLastName().concat(", ").concat(getFirstName());
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public Date getLastLogin() {
		return lastLogin;
	}

	public void setLastLogin(Date lastLogin) {
		this.lastLogin = lastLogin;
	}

	public String getDni() {
		return dni;
	}

	public void setDni(String dni) {
		this.dni = dni;
	}

	public void setAutorized(boolean autorized) {
		this.autorized = autorized;
	}

	public void setDocumentType(DocumentType documentType) {
		this.documentType = documentType;
	}

	public DocumentType getDocumentType() {
		return documentType;
	}

	public Boolean getAutorized() {
		return autorized;
	}

	public void setAutorized(Boolean autorized) {
		this.autorized = autorized;
	}

	public List<UserRole> getRoles() {
		return roles;
	}

	public void setRoles(List<UserRole> roles) {
		this.roles = roles;
	}

	@Override
	public Collection<GrantedAuthority> getAuthorities() {
		List<GrantedAuthority> roles = new ArrayList<GrantedAuthority>();
		for (Role role : getActiveRoles()) {
			roles.add(new GrantedAuthorityImpl(role.getDescription()));
		}
		return roles;
	}

	@Override
	public String getUsername() {
		return username;
	}

	@Override
	public boolean isAccountNonExpired() {
		return isActive();
	}

	@Override
	public boolean isAccountNonLocked() {
		return isActive();
	}

	@Override
	public boolean isCredentialsNonExpired() {
		return isActive();
	}

	@Override
	public boolean isEnabled() {
		return isActive();
	}

	public List<UserPhone> getUserPhone() {
		return userPhone;
	}

	public void setUserPhone(List<UserPhone> userPhone) {
		this.userPhone = userPhone;
	}

	public List<UserEmail> getUserEmail() {
		return userEmail;
	}

	public void setUserEmail(List<UserEmail> userEmail) {
		this.userEmail = userEmail;
	}

	public String getConfirmPassword() {
		return confirmPassword;
	}

	public void setConfirmPassword(String confirmPassword) {
		this.confirmPassword = confirmPassword;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getTheme() {
		return theme;
	}

	public void setTheme(String theme) {
		this.theme = theme;
	}
	
	public UserEmail getDefaultEmail() {
		for (UserEmail email : this.getUserEmail()) {
			if(email.getIsDefault() && email.getActive()) {
				return email;
			}
		}
		return null;
	}
	
	public UserPhone getDefaultPhone() {
		for (UserPhone phone : this.getUserPhone()) {
			if(phone.getIsDefault() && phone.getActive()) {
				return phone;
			}
		}
		return null;
	}
	
	

	public List<Operation> getOperation() {
		return operation;
	}

	public void setOperation(List<Operation> operation) {
		this.operation = operation;
	}

	public String getCuil() {
		return cuil;
	}

	public void setCuil(String cuil) {
		this.cuil = cuil;
	}

	public int getLoginAttemp() {
		return loginAttemp;
	}

	public void setLoginAttemp(int loginAttemp) {
		this.loginAttemp = loginAttemp;
	}
	
	public List <UserEmail> getActiveUserEmail(){
		List <UserEmail> activeUserEmail = new ArrayList<UserEmail>();
		for (UserEmail userEmail : getUserEmail()) {
			if(userEmail.isActive()) {
				activeUserEmail.add(userEmail);
			}
		}
		return activeUserEmail;
	}
	
	public List <UserPhone> getActiveUserPhone(){
		List <UserPhone> activeUserPhone = new ArrayList<UserPhone>();
		for (UserPhone userPhone : getUserPhone()) {
			if(userPhone.isActive()) {
				activeUserPhone.add(userPhone);
			}
		}
		return activeUserPhone;
	}

	public Boolean getBlock() {
		return block;
	}

	public void setBlock(Boolean block) {
		this.block = block;
	}

	public String getBlockMotive() {
		return blockMotive;
	}

	public void setBlockMotive(String blockMotive) {
		this.blockMotive = blockMotive;
	}
	
}